﻿import 'dart:developer' as developer;
import 'package:get/get.dart';
import '../../../core/controllers/ring_controller.dart';
import '../../../core/repository/default_api.dart';
import '../../../services/device_sn_manager.dart';
import '../../../services/ring_service.dart';
import '../status_logic.dart';

/// 时间范围
enum PressureTimeRange { day, week, month }

/// 压力页面数据
class PressureViewData {
  final int score;
  final List<int> hourly;
  final List<PressureRatioData> ratios;
  final String? dateStart;
  final String? dateEnd;
  final String? recordDate;
  final String? weekName;
  final List<PressureDataPoint> dataPoints;
  final List<PressureDataPoint> manualRecords; // 手动测量记录

  const PressureViewData({
    required this.score,
    required this.hourly,
    this.ratios = const [],
    this.dateStart,
    this.dateEnd,
    this.recordDate,
    this.weekName,
    this.dataPoints = const [],
    this.manualRecords = const [],
  });
}

/// 压力数据点
class PressureDataPoint {
  final String code;
  final int? value;
  final int? maxValue;
  final int? minValue;
  final int? number;

  PressureDataPoint({
    required this.code,
    this.value,
    this.maxValue,
    this.minValue,
    this.number,
  });

  factory PressureDataPoint.fromJson(Map<String, dynamic> json) {
    int? parseInt(dynamic value) {
      if (value == null) return null;
      if (value is int) return value;
      if (value is double) return value.toInt();
      if (value is String) return int.tryParse(value);
      return null;
    }

    return PressureDataPoint(
      code: json['code']?.toString() ?? '',
      value: parseInt(json['value']),
      maxValue: parseInt(json['maxValue']),
      minValue: parseInt(json['minValue']),
      number: parseInt(json['number']),
    );
  }
}

/// 压力比例数据
class PressureRatioData {
  final String info; // 优秀、良好、合格、不足
  final int value; // 百分比值
  const PressureRatioData({required this.info, required this.value});
}

/// 压力控制器
class PressureLogic extends GetxController {
  static const String _tag = 'PressureLogic';

  final Rx<PressureTimeRange> currentRange = PressureTimeRange.day.obs;
  final Rx<PressureViewData?> data = Rx<PressureViewData?>(null);

  // 测量相关
  final RxBool isMeasuring = false.obs;
  final RxInt currentPressureValue = 0.obs;

  // 获取戒指控制器和状态控制器
  RingController get ringController => Get.find<RingController>();
  StatusLogic get statusLogic => Get.find<StatusLogic>();

  @override
  void onInit() {
    super.onInit();
    _loadData();
    _setupDataListener();
    _setupStressDataListener();
    // 延迟调用API，避免在构建阶段调用
    Future.delayed(const Duration(milliseconds: 100), () {
      _fetchPressureData();
    });
  }

  void setTimeRange(PressureTimeRange range) {
    currentRange.value = range;
    _loadData();
    // 切换时间范围时重新获取数据
    _fetchPressureData();
  }

  /// 设置数据监听器
  void _setupDataListener() {
    // 监听压力数据变化
    ever(ringController.todayStressListRx, (List<int?> stressList) {
      if (stressList.isNotEmpty) {
        _loadData();
      }
    });
  }

  /// 设置压力数据监听器（用于手动测量）
  void _setupStressDataListener() {
    // 监听单次压力测量数据变化
    ever(ringController.stressDataRx, (StressData? stressData) {
      if (stressData != null && isMeasuring.value && stressData.stress > 0) {
        developer.log('🎯 监听到压力数据变化: ${stressData.stress}，触发测量完成处理', name: _tag);
        isMeasuring.value = false;
        _handleMeasurementComplete();
      }
    });
  }

  void _loadData() {
    // 从API数据加载
    if (data.value != null) {
      return; // 已有数据，不重新加载
    }
  }

  /// 加载默认数据
  void _loadDefaultData() {
    final values = List<int>.generate(24, (i) => 20 + (i % 12));
    data.value = PressureViewData(score: 27, hourly: values);
  }

  /// 解析压力数据
  void _parsePressureData(Map<String, dynamic> responseData) {
    try {
      final average = responseData['average'] as int? ?? 0;
      final dateStart = responseData['dateStart'] as String?;
      final dateEnd = responseData['dateEnd'] as String?;
      final recordDate = responseData['recordDate'] as String?;
      final weekName = responseData['weekName'] as String?;
      final automaticInfoList =
          responseData['automaticInfoVOS'] as List<dynamic>? ?? [];
      final manualInfoList =
          responseData['manualInfoVOS'] as List<dynamic>? ?? [];

      // 解析自动数据点
      final List<PressureDataPoint> dataPoints = [];
      for (var info in automaticInfoList) {
        if (info is Map<String, dynamic>) {
          dataPoints.add(PressureDataPoint.fromJson(info));
        }
      }

      // 解析手动测量记录
      final List<PressureDataPoint> manualRecords = [];
      for (var info in manualInfoList) {
        if (info is Map<String, dynamic>) {
          manualRecords.add(PressureDataPoint.fromJson(info));
        }
      }

      // 创建24小时的压力值数组（每小时取平均值）
      final List<int> hourlyValues = List.filled(24, 0);

      // 遍历所有5分钟间隔的数据点
      for (var point in dataPoints) {
        final value = point.value ?? 0;
        if (value > 0) {
          // 解析时间 "HH:mm"
          final timeParts = point.code.split(':');
          if (timeParts.length == 2) {
            final hour = int.tryParse(timeParts[0]) ?? 0;
            if (hourlyValues[hour] == 0 || value > hourlyValues[hour]) {
              hourlyValues[hour] = value;
            }
          }
        }
      }

      // 更新数据，保留现有的ratios
      data.value = PressureViewData(
        score: average,
        hourly: hourlyValues,
        ratios: data.value?.ratios ?? [],
        dateStart: dateStart,
        dateEnd: dateEnd,
        recordDate: recordDate,
        weekName: weekName,
        dataPoints: dataPoints,
        manualRecords: manualRecords,
      );

      developer.log('✅ 压力数据解析完成: 平均值=$average, 手动记录=${manualRecords.length}条', name: _tag);
    } catch (e) {
      developer.log('❌ 解析压力数据失败: $e', name: _tag);
      _loadDefaultData();
    }
  }

  /// 获取压力页面数据
  Future<void> _fetchPressureData() async {
    try {
      developer.log('📊 开始获取压力页面数据...', name: _tag);

      // 获取设备序列号
      // final deviceSn = ringController.getCurrentDeviceSn();
      // if (deviceSn.isEmpty) {
      //   developer.log('❌ 设备未连接，无法获取压力数据', name: _tag);
      //   return;
      // }

      // 获取设备SN
      final deviceSnManager = Get.find<DeviceSnManager>();
      final deviceSn = deviceSnManager.getDeviceSn();

      if (deviceSn.isEmpty) {
        developer.log('⚠️ 设备SN为空，无法获取压力数据', name: _tag);
        return;
      }

      // 获取当前日期
      final now = DateTime.now();
      final recordDate =
          '${now.year}-${now.month.toString().padLeft(2, '0')}-${now.day.toString().padLeft(2, '0')}';

      developer.log('📅 设备序列号: $deviceSn, 日期: $recordDate', name: _tag);

      // 并行调用两个压力接口
      await Future.wait([
        _fetchPressureAverage(deviceSn, recordDate),
        _fetchPressureMonitor(deviceSn, recordDate),
      ]);

      developer.log('✅ 压力页面数据获取完成', name: _tag);
    } catch (e) {
      developer.log('❌ 获取压力页面数据异常: $e', name: _tag);
    }
  }

  /// 获取当前时间范围对应的type值
  String _getTypeFromTimeRange() {
    switch (currentRange.value) {
      case PressureTimeRange.day:
        return '1';
      case PressureTimeRange.week:
        return '2';
      case PressureTimeRange.month:
        return '3';
    }
  }

  /// 获取压力平均值
  Future<void> _fetchPressureAverage(String deviceSn, String recordDate) async {
    try {
      final response = await DefaultApi().queryPressureAverageGet(
        deviceSn: deviceSn,
        recordDate: recordDate,
        type: _getTypeFromTimeRange(),
        isShowErrMsg: false,
        isShowLoading: false,
      );
      developer.log('✅ 压力平均值获取成功: $response', name: _tag);

      // 解析并更新数据
      if (response != null && response is Map<String, dynamic>) {
        final responseData = response['data'] as Map<String, dynamic>?;
        if (responseData != null) {
          _parsePressureData(responseData);
        }
      }
    } catch (e) {
      developer.log('❌ 获取压力平均值失败: $e', name: _tag);
      _loadDefaultData();
    }
  }

  /// 获取压力比例
  Future<void> _fetchPressureMonitor(String deviceSn, String recordDate) async {
    try {
      final response = await DefaultApi().queryPressureMonitorGet(
        deviceSn: deviceSn,
        recordDate: recordDate,
        type: _getTypeFromTimeRange(),
        isShowErrMsg: false,
        isShowLoading: false,
      );
      developer.log('✅ 压力比例获取成功: $response', name: _tag);

      // 解析比例数据
      if (response != null && response is Map<String, dynamic>) {
        final dataList = response['data'] as List<dynamic>?;
        if (dataList != null) {
          _parsePressureRatios(dataList);
        }
      }
    } catch (e) {
      developer.log('❌ 获取压力比例失败: $e', name: _tag);
    }
  }

  /// 解析压力比例数据
  void _parsePressureRatios(List<dynamic> dataList) {
    try {
      final List<PressureRatioData> ratios = [];

      for (var item in dataList) {
        if (item is Map<String, dynamic>) {
          final info = item['info'] as String? ?? '';
          final value = item['value'] as int? ?? 0;
          ratios.add(PressureRatioData(info: info, value: value));
        }
      }

      // 更新数据，保留现有的score和hourly，如果没有则使用默认值
      if (data.value != null) {
        data.value = PressureViewData(
          score: data.value!.score,
          hourly: data.value!.hourly,
          ratios: ratios,
          manualRecords: data.value!.manualRecords,
        );
      } else {
        // 如果还没有数据，创建一个默认的
        data.value = PressureViewData(
          score: 0,
          hourly: List.filled(24, 0),
          ratios: ratios,
        );
      }

      developer.log('✅ 压力比例数据解析完成: ${ratios.length}项, ratios=$ratios',
          name: _tag);
    } catch (e) {
      developer.log('❌ 解析压力比例数据失败: $e', name: _tag);
    }
  }

  /// 手动刷新数据
  void refreshData() {
    _fetchPressureData();
  }

  /// 开始压力测量
  Future<void> startPressureMeasurement() async {
    developer.log('🚀 开始压力测量', name: _tag);
    try {
      isMeasuring.value = true;
      developer.log('🚀 测量状态已设置为true', name: _tag);

      // 启动压力测量
      await ringController.startStressMeasure();
      developer.log('🚀 戒指控制器压力测量已启动', name: _tag);

      // 开始测量后，定期检查压力数据变化
      _startPressureDataCheck();
    } catch (e) {
      developer.log('❌ 开始压力测量失败: $e', name: _tag);
      isMeasuring.value = false;
    }
  }

  /// 停止压力测量
  Future<void> stopPressureMeasurement() async {
    try {
      await ringController.stopStressMeasure();
      isMeasuring.value = false;

      // 停止测量后，处理测量结果
      _handleMeasurementComplete();
    } catch (e) {
      developer.log('❌ 停止压力测量失败: $e', name: _tag);
    }
  }

  /// 开始压力数据检查
  void _startPressureDataCheck() {
    int lastStress = ringController.stressData?.stress ?? 0;
    developer.log('🔍 开始压力数据检查，初始压力: $lastStress', name: _tag);
    
    // 开始定期检查压力数据变化
    _checkPressureData(lastStress);
  }

  /// 检查压力数据
  void _checkPressureData(int lastStress) {
    if (!isMeasuring.value) {
      developer.log('🔍 测量已停止，取消检查', name: _tag);
      return;
    }

    final currentStress = ringController.stressData?.stress ?? 0;
    if (currentStress != lastStress && currentStress > 0) {
      developer.log('✅ 检测到压力数据变化，触发测量完成处理', name: _tag);
      isMeasuring.value = false;
      _handleMeasurementComplete();
      return;
    }

    if (!ringController.isStressMeasuring) {
      developer.log('🔍 测量状态已停止，触发测量完成处理', name: _tag);
      isMeasuring.value = false;
      _handleMeasurementComplete();
      return;
    }

    Future.delayed(const Duration(seconds: 1), () {
      _checkPressureData(currentStress);
    });
  }

  /// 处理测量完成
  void _handleMeasurementComplete() {
    developer.log('🎯 开始处理压力测量完成', name: _tag);

    // 获取最新的压力数据
    final stressData = ringController.stressData;
    final currentStress = stressData?.stress ?? 0;

    developer.log('🎯 当前压力数据: $currentStress', name: _tag);

    if (currentStress > 0) {
      developer.log('🎯 压力数据有效，开始处理', name: _tag);

      // 更新当前压力值
      currentPressureValue.value = currentStress;

      // 上报压力数据到服务器
      _reportPressureToServer(currentStress);

      // 刷新页面数据
      _fetchPressureData();
    } else {
      developer.log('❌ 压力数据无效: $currentStress', name: _tag);
    }
  }

  /// 上报压力数据到服务器
  Future<void> _reportPressureToServer(int stress) async {
    developer.log('📤 开始上报压力数据: $stress', name: _tag);

    try {
      final deviceSn = ringController.getCurrentDeviceSn();
      if (deviceSn.isEmpty) {
        developer.log('❌ 设备未连接，无法上报压力数据', name: _tag);
        return;
      }

      developer.log('📤 上报参数: deviceSn=$deviceSn, stressChange=$stress',
          name: _tag);

      await DefaultApi().addStressChangePost<Map<String, dynamic>>(
        deviceSn: deviceSn,
        stressChange: stress.toString(),
        isShowErrMsg: false,
        isShowLoading: false,
      );

      developer.log('✅ 压力数据上报成功', name: _tag);
    } catch (e) {
      developer.log('❌ 压力数据上报异常: $e', name: _tag);
    }
  }

  /// 获取日期标题（根据时间范围使用不同字段）
  String getDateTitle() {
    final pressureData = data.value;

    if (pressureData != null) {
      // 周和月视图使用 dateStart 和 dateEnd
      if (currentRange.value == PressureTimeRange.week ||
          currentRange.value == PressureTimeRange.month) {
        if (pressureData.dateStart != null && pressureData.dateEnd != null) {
          return '${pressureData.dateStart} - ${pressureData.dateEnd}';
        }
      }

      // 日视图使用 recordDate 和 weekName
      if (currentRange.value == PressureTimeRange.day &&
          pressureData.recordDate != null &&
          pressureData.recordDate!.isNotEmpty) {
        return '${pressureData.recordDate}，${pressureData.weekName}，00:00 平均';
      }
    }

    // 降级方案：使用当前日期
    final d = DateTime.now();
    const weekdays = ['周一', '周二', '周三', '周四', '周五', '周六', '周日'];
    final weekday = weekdays[(d.weekday - 1).clamp(0, 6)];
    return '${d.year}年${d.month.toString().padLeft(2, '0')}月${d.day.toString().padLeft(2, '0')}日，$weekday，00:00 平均';
  }

  /// 根据指定日期加载数据
  void loadDataByDate(String recordDate) {
    developer.log('📅 根据日期加载压力数据: $recordDate', name: _tag);
    
    // 获取设备SN
    final deviceSnManager = Get.find<DeviceSnManager>();
    final deviceSn = deviceSnManager.getDeviceSn();

    if (deviceSn.isEmpty) {
      developer.log('⚠️ 设备SN为空，无法获取压力数据', name: _tag);
      return;
    }

    // 并行调用两个压力接口
    Future.wait([
      _fetchPressureAverage(deviceSn, recordDate),
      _fetchPressureMonitor(deviceSn, recordDate),
    ]);
  }
}
